package invite_service

import (
	"crypto/sha1"
	"fmt"
	"io"
	"shimmer/neusoft_club_backend/dao/domain"
	"shimmer/neusoft_club_backend/services"
	"strconv"
	"time"
)

type InviteParameters struct {
	ClubID    int64 `json:"club_id" form:"club_id"  binding:"required"`
	BeginTime int64 `json:"begin_time" form:"begin_time" bind:"required"`
	EndTime   int64 `json:"end_time" form:"end_time" binding:"required"`
}

type InviteLinkParameters struct {
	InviteParameters
	Signature string `json:"signature" form:"signature"  binding:"required"`
}

func FindInviteLinkByID(id int64) (res *domain.ClubInviteLink, err error) {
	res = &domain.ClubInviteLink{ID: id}
	err = services.DBEngine.Joins(domain.ClubInviteLinkFieldClub).Preload(fmt.Sprintf("%s.%s", domain.ClubInviteLinkFieldInviter, domain.UserFieldAvatar)).First(res).Error
	if err != nil {
		return
	}
	return
}
func SignInvite(parameters *InviteParameters) (res string, err error) {
	clubID, beginTime, endTime := parameters.ClubID, parameters.BeginTime, parameters.EndTime
	decoder := sha1.New()
	if _, err = io.WriteString(decoder, strconv.FormatInt(clubID, 10)); err != nil {
		return
	}
	if _, err = io.WriteString(decoder, "&"); err != nil {
		return
	}
	if _, err = io.WriteString(decoder, strconv.FormatInt(beginTime, 10)); err != nil {
		return
	}
	if _, err = io.WriteString(decoder, "&"); err != nil {
		return
	}
	if _, err = io.WriteString(decoder, strconv.FormatInt(endTime, 10)); err != nil {
		return
	}
	return fmt.Sprintf("%x", decoder.Sum(nil)), nil
}

func ValidateInviteSignature(parameters *InviteLinkParameters) (res bool, err error) {
	sign, err := SignInvite(&parameters.InviteParameters)
	return sign == parameters.Signature, nil
}

func CreateInviteLink(userId int64, parameters *InviteParameters) (res *domain.ClubInviteLink, signature string, err error) {
	res = &domain.ClubInviteLink{
		InviterID:  userId,
		ClubID:     parameters.ClubID,
		ExpireTime: time.Unix(parameters.EndTime, 0),
	}
	if err = services.DBEngine.Save(res).Error; err != nil {
		return
	}
	if signature, err = SignInvite(parameters); err != nil {
		return
	}
	return
}

func DeleteInviteLink(id int64) (err error) {
	err = services.DBEngine.Delete(&domain.ClubInviteLink{ID: id}).Error
	if err != nil {
		return
	}
	return
}
